#include "parse_map_from_keil.h"
#include <QFile>
#include <QDomDocument>
#include <Qtxml>
#include <QDebug>
#include <qxmlstream.h>
#include "find_path.h"
#include <QRegExp>


#include "mainwindow.h"
#include "ui_mainwindow.h"
extern MainWindow* main_window;

QString parse_map_from_keil::find_map_path(const QString& dir_path)
{


    QString map_file_path;
    map_file_path=find_path::find_file_path(dir_path,".map");
    if(map_file_path.length()<3)
        map_file_path=find_path::find_file_path(dir_path,".MAP");

    return map_file_path;



}

bool parse_map_from_keil::parse_excution_region_info(QString info_string)
{

    //    storage_type_t storage=ram;
    use_percentage_bar* storage=new use_percentage_bar(nullptr);
    storage->setStorage(flash);
    for(auto keyword:ram_keyword)
    {
        if(info_string.contains(keyword))
        {
            //            qDebug()<<info_string;
            storage->setStorage(ram);
        }
    }




    info_string.remove("Execution Region", Qt::CaseInsensitive);//去除"Execution Region"
    info_string.remove(QChar(' '), Qt::CaseInsensitive);//去除" "

    storage->setName(info_string.split("(")[0]);
    QStringList info_list =info_string.split("(")[1].split(",");



    for(auto info :info_list)
    {
        QStringList info_value;
        info.remove(QChar(','), Qt::CaseInsensitive);//去除","
        info.remove(QChar(' '), Qt::CaseInsensitive);//去除")"


        if(info.contains("Exec")||info.contains("Base"))
        {
            info_value =info.split(":");
            info_value[1].remove(QChar('x'), Qt::CaseInsensitive);//去除"x"
            storage->setBase_addr(info_value[1].toUInt(nullptr,16));
            //            qDebug()<<info_value[1];

            if(storage->getBase_addr()>iram_base&&storage->getBase_addr()<iram_base+iram_max_size)
                storage->setStorage(ram);
            else if(storage->getBase_addr()>irom_base&&storage->getBase_addr()<irom_base+irom_max_size)
                storage->setStorage(flash);

        }else if(info.contains("Size"))
        {

            info_value =info.split(":");
            info_value[1].remove(QChar('x'), Qt::CaseInsensitive);//去除"x"

            storage->setUsed_size(info_value[1].toUInt(nullptr,16));
            //            qDebug()<<info_value[1];



        }else if(info.contains("Max"))
        {

            info_value =info.split(":");
            info_value[1].remove(QChar('x'), Qt::CaseInsensitive);//去除"x"
            storage->setMax_size(info_value[1].toUInt(nullptr,16));
            //            qDebug()<<info_value[1];

        }



    }



    if(storage->getStorage()==ram)
        ram_list.append(storage);
    else
        flash_list.append(storage);


}

bool parse_map_from_keil::parse_map_file(QString path){

    QFile file(path);

    bool is_Image_component_sizes=false;
    bool is_Totals=false;


    for(auto info:info_list)
    {
        delete  info;
    }
    info_list.clear();

    for(auto ram:ram_list)
    {
        delete  ram;
    }
    ram_list.clear();


    for(auto flash:flash_list)
    {
        delete  flash;
    }
    flash_list.clear();



    if (!file.open(QIODevice::ReadOnly))
    {
        qDebug()<<"open fail"<<endl;
        return false;
    }

    while (!file.atEnd())
    {
        QByteArray line = file.readLine();
        QString str(line);

        if(str.contains("Execution Region"))
        {

            //                    qDebug() << str;
            parse_excution_region_info(str);
        }else if(str.contains("Image component sizes"))
        {
            is_Image_component_sizes=true;
            //                       qDebug()<<str;
        }

        if(is_Image_component_sizes)
        {
            if(str.contains("----"))
            {
                if(is_Totals)
                {
                    is_Totals=false;
                }else
                {
                    is_Totals=true;

                }

            }
            else if(str.contains("=====")){
                is_Image_component_sizes=false;
            }else if(str==""||str.length()<10)
            {

            }
            else {
                // 使用正则表达式提取数字和单词
                QRegExp rx("(\\d+|\\w+)");

                // 将多个空格替换为逗号
                QString csv_row = str.trimmed().replace(QRegExp("\\s+"), ",");
                csv_row+="\n";
                // 输出修改后的数据
                //                        qDebug() << csv_row;

                QStringList item_data=  csv_row.split(",");


                if(item_data.length()<=8)
                {
                    bool is_number=false;
                    if(is_Totals)
                    {
                        if(item_data.length()>7&&item_data[7].contains("Totals"))
                        {

                            continue;

                        }
                    }

                    item_data[1].toUInt(&is_number);
                    if(is_number)
                    {

                        image_item_t* item=new image_item_t();
                        item->Code=QString::number(item_data[0].toInt());//item_data[1].toUInt()(inc.data是包含在code内的)
                        item->RO_Data=item_data[2];
                        item->RW_Data=item_data[3];
                        item->ZI_Data=item_data[4];
                        item->Debug=item_data[5];
                        item->Object_Name=item_data[6];

                        if(item->Object_Name.contains(".l"))
                            continue;
                        else if (item->Object_Name.contains("(")) {
                            item->Object_Name=item->Object_Name=item_data[6]+item_data[7];

                        }

                        info_list.append(item);

                    }

                }



            }
        }
    }


    qDebug()<<"ram:";
    for(auto ram:ram_list)
    {
        ram->print_bar();
    }
    qDebug()<<"flash:";
    for(auto flash:flash_list)
    {
        flash->print_bar();
    }

    file.close();


}

QString parse_map_from_keil::getMap_path() const
{
    return map_path;
}

void parse_map_from_keil::setMap_path(const QString &value)
{
    map_path = value;
}

QList<image_item_t*> parse_map_from_keil::getInfo_list() const
{
    return info_list;
}

void parse_map_from_keil::setInfo_list(const QList<image_item_t*> &value)
{
    info_list = value;
}

uint64_t parse_map_from_keil::getAll_ram_size() const
{
    return all_ram_size;
}

uint64_t parse_map_from_keil::getAll_flash_size() const
{
    return all_flash_size;
}



bool parse_map_from_keil::to_parse_map_from_keil(QString path)
{

    map_path=path;
    QString file_path;


    if(path.contains(".map")||path.contains(".MAP"))
    {
        parse_map_file(path);
        return true;
    }



    file_path=find_map_path(path);
    qDebug()<<file_path;

    if(file_path.length()>3)
    {
        parse_map_file(file_path);
        return true;
    }else
    {
        qDebug()<<"路径错误,请检测输入的工程路径！";
        main_window->winow_on_top(false);
        QMessageBox::critical(nullptr, "Error", "路径错误,请检测输入的工程路径！");

        return false;
    }
}

parse_map_from_keil::parse_map_from_keil(QString path,   uint64_t to_iram_base,
                                         uint64_t to_iram_max_size,
                                         uint64_t to_irom_base,
                                         uint64_t to_irom_max_size)
{


    iram_base=to_iram_base;
    iram_max_size=to_iram_base;
    irom_base=to_irom_base;
    irom_max_size= to_irom_max_size;

    //to_parse_map_from_keil(path);

}
